
#if !defined RELIABLE_CONNECTION_H 
#define RELIABLE_CONNECTION_H

#include "RtCnReconn.h"

class CCacheBuff
{
	typedef struct Data_Node
	{
		DWORD	m_dwStartSequence;
		DWORD	m_dwLeftDataLength;
		const DWORD	m_dwOrgDataLength;
		CRtMessageBlock *m_pmbDataBlock;
		Data_Node	*m_pNext;
		Data_Node(DWORD dwSequence, DWORD dwDataLen, CRtMessageBlock &DataBk)
			:m_dwOrgDataLength(dwDataLen)
		{
			m_dwStartSequence = dwSequence;
			m_pmbDataBlock = DataBk.DuplicateChained();
			if(!m_pmbDataBlock)
			{
				RT_ERROR_TRACE_THIS("Data_Node::Data_Node out of memory");
				m_dwLeftDataLength = 0;
			}
			else
			{
				m_dwLeftDataLength = dwDataLen;
			}
			m_pNext = NULL;
		}
		~Data_Node()
		{
			if(m_pmbDataBlock)
			{
				m_pmbDataBlock->DestroyChained();
			}
		}
	}Node_t;

	Node_t	*m_pBeginNode;
	Node_t	*m_pCursorNode;
	Node_t	*m_pEndNode;
	DWORD	m_dwCachedDataSize;
	DWORD	m_dwLatestRemovePosition;
	DWORD	m_dwSequence;
public:
	CCacheBuff();
	~CCacheBuff();

	RtResult AddData(CRtMessageBlock &DataMsg);
	RtResult RemoveData(DWORD dwEndSeq);
	RtResult Next();
	void Rewind();
	CRtMessageBlock * GetData(BOOL &bIsPart);
	inline DWORD GetCachedDataSize();
	inline void Disable();
	void Clear();
	

};

//////////////////////////////////////////////////////////////////////////

class CRLBClient: public CReconnClient
{
public:
	CRLBClient(IConnectorT *pConnector);
	virtual ~CRLBClient();
	virtual RtResult SendData(CRtMessageBlock &aData, CRtTransportParameter *pParameter = NULL);
		
protected:
	virtual void OnReceiveConnectResponse(CRespPDU &responsePDU);
	virtual void OnACK(DWORD dwACKSequence);
	virtual void OnSend(IRtTransport *pTransport, CRtTransportParameter *pParameter = NULL);
	BOOL NeedKeepaliveFlag();
	void OnTimer(CRtTimerWrapper *aId);
	virtual void OnDisconnect(RtResult aReason,	IRtTransport *pTransport);
protected:
	CCacheBuff			m_CachedSendData;
	CRtTimerWrapper	m_PersistTimer;
};

//////////////////////////////////////////////////////////////////////////

class CRLBServer: public CReconnServer
{
public:
	CRLBServer(IRtTransport *pTransport
		, ConnectionList_T *pConnectionList
		, IRtTransportSink* pITransportSink);

	virtual ~CRLBServer();

	virtual RtResult Attach(IRtTransport *pTransport, DWORD dwAck);
	RtResult SendData(CRtMessageBlock &aData, CRtTransportParameter *pParameter = NULL);
protected:
	virtual void OnACK(DWORD dwACKSequence);
	virtual void OnSend(IRtTransport *pTransport, CRtTransportParameter *pParameter = NULL);
	BOOL NeedKeepaliveFlag();

	virtual void OnDisconnect(RtResult aReason,	IRtTransport *pTransport);
	void OnTimer(CRtTimerWrapper *aId);
	
protected:
	CCacheBuff	m_CachedSendData;	
	CRtTimerWrapper		m_PersistTimer;
};

#endif
